package org.mf.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.mf.dao.GenericDao;
import org.mf.web.pagination.PagedResultSet;
import org.mf.web.pagination.Pager;
import org.springframework.dao.support.DataAccessUtils;

@SuppressWarnings("unchecked")
public class GenericDaoJpa<T extends Object> implements GenericDao<T> {
	private Class<T> type;

	@PersistenceContext(unitName = "")
	private EntityManager entityManager;

	public GenericDaoJpa(Class<T> type) {
		super();
		this.type = type;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public T get(Long id) {
		return (T) entityManager.find(type, id);
	}

	public List<T> getAll(Pager pager) {
		System.out.println("jpa getting paginated objects objects");
		StringBuilder sb = new StringBuilder();
		sb.append("select obj from").append(" ").append(type.getName())
				.append(" ").append("obj").append(" ");
		if (pager.getSortOrder() == "asc") {
			sb.append("order by").append(" ").append(pager.getSortColumn())
					.append(" ").append("asc").append(" ");
		} else {
			sb.append("order by").append(" ").append(pager.getSortColumn())
					.append(" ").append("desc").append(" ");
		}
		return entityManager.createQuery(sb.toString())
				.setFirstResult((pager.getPage() - 1) * pager.getPageSize())
				.setMaxResults(pager.getPageSize()).getResultList();
	}

	public List<T> getAll() {
		System.out.println("jpa getting all objects");
		return entityManager.createQuery(
				"select obj from " + type.getName() + " obj").getResultList();
	}

	public PagedResultSet getPagedResults(Pager pager) {
		List<T> pagedResultSet = this.getAll(pager);
		PagedResultSet pr = new PagedResultSet();
		pr.setPager(pager);
		pr.setResultSet(pagedResultSet);
		pr.setRowCount(this.getAllCount());
		return pr;
	}

	public void save(T object) {
		System.out.println("jpa saving object");
		entityManager.merge(object);
	}

	public void delete(T object) {
		entityManager.remove(object);
	}

	public Integer getAllCount() {
		Long cnt = (Long) entityManager.createQuery(
				"select count(obj.id) from " + type.getName() + " obj")
				.getSingleResult();
		int count = cnt.intValue();
		return count;
	}

	public Boolean isUnique(Long id, String fieldName, String fieldValue) {
		StringBuilder sb = new StringBuilder();
		sb.append("select count(*) from ");
		sb.append(type.getName());
		sb.append(" obj ");
		sb.append("where obj. ");
		sb.append(fieldName);
		sb.append(" = :username");
		if (id != null) {
			sb.append(" and id <> :id");
		}
		int count = 0;
		if (id != null) {
			Long longCount = (Long) entityManager.createQuery(sb.toString())
					.setParameter("id", id).setParameter(fieldName, fieldValue)
					.getSingleResult();
			count = longCount.intValue();
		} else {
			Long longCount = (Long) entityManager.createQuery(sb.toString())
					.setParameter(fieldName, fieldValue).getSingleResult();
			count = longCount.intValue();
		}
		if (count == 0) {
			return true;
		} else {
			return false;
		}

	}

}
